package full_search;

import agents.AutomatonAgent;
import env.Action;
import env.Enviroment;
import env.Orientation;
import env.Tile;
import java.util.Vector;

/**
 * TODO: ?? use this class instead of passing around row, col, and orientation???
 * @author user
 */
public class FullState {

    private int row;
    private int col;
    private Orientation orientation;
    private Vector<Tile> flags;
    private AutomatonAgent sentry; //for the sentry!
    public boolean isAlive;
    public boolean capture = false;

    public FullState(int row, int col, Orientation orientation, Vector<Tile> flags, AutomatonAgent sentry, boolean isAlive) {
        this.row = row;
        this.col = col;
        this.orientation = orientation;
        //this.flags = new Vector<Tile>(flags);
        this.flags = flags;

        //TODO: make a sentry Factory, that gives 1 of n possible sentries
        if (sentry != null) {
            this.sentry = new AutomatonAgent(sentry); //copy-constructor
        }
        this.isAlive = isAlive;
    }

    public int getCol() {
        return col;
    }

    public Orientation getOrientation() {
        return orientation;
    }

    public int getRow() {
        return row;
    }

    public Vector<Tile> getFlags() {
        return flags;
    }

    public AutomatonAgent getSentry() {
        return sentry;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final FullState other = (FullState) obj;
        if (this.row != other.row) {
            return false;
        }
        if (this.col != other.col) {
            return false;
        }
        if (this.orientation != other.orientation) {
            return false;
        }
        if (this.flags != other.flags && (this.flags == null || !this.flags.equals(other.flags))) {
            return false;
        }
        if (this.sentry != other.sentry && (this.sentry == null || !this.sentry.equals(other.sentry))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 43 * hash + this.row;
        hash = 43 * hash + this.col;
        hash = 43 * hash + (this.orientation != null ? this.orientation.hashCode() : 0);
        hash = 43 * hash + (this.flags != null ? this.flags.hashCode() : 0);
        hash = 43 * hash + (this.sentry != null ? this.sentry.hashCode() : 0);
        return hash;
    }

    public void update(Action move) {
        if (move == Action.fwd) {
            switch (orientation) {
                case North: {
                    row--;
                    break;
                }
                case East: {
                    col++;
                    break;
                }
                case West: {
                    col--;
                    break;
                }
                case South: {
                    row++;
                    break;
                }


            }
            if (flags.contains(Enviroment.env.map[row][col])) {
                capture = true;//System.out.println("flag picked up at "+row+", "+col); //PICK-UP!!
                Vector<Tile> temp = new Vector<Tile>();
                for (Tile f : flags) {
                    if (f != Enviroment.env.map[row][col]) {
                        temp.add(f);
                    }
                }
                flags = temp;
            }

        } else {
            orientation = Orientation.turn(orientation, move);
        }
        
        if (sentry != null) {
            if (sentry.isInLineOfSight(row, col)) {
                isAlive = false;
                //System.out.println("-----  " + this + " changed to death!");
            }
            sentry.updatePosition(sentry.getMove());
        }

    }

    public FullState clone(Action move) {
        FullState s = new FullState(row, col, orientation, flags, sentry, isAlive);
        s.update(move);
        return s;
    }

    @Override
    public String toString() {
        return "state: pos=" + row + "," + col + " " + orientation + ",  sentry at " + (sentry != null ? sentry.getCol() : "nowhere!") + "  #f=" + flags.size() + " alive?=" + isAlive;
    }
}
